\chapter{Connessione TCP: Il working thread}
Il TCP nacque nel 1970 come frutto del lavoro di un gruppo di ricerca del dipartimento di difesa statunitense. I suoi punti di forza sono l'alta affidabilità e robustezza.
Il protocollo TCP serve a creare degli stream socket, cioè una forma di canale di comunicazione che stabilisce una connessione stabile fra due stazioni, in modo che queste possano scambiarsi dei dati.

Nel progetto Mini-KaZaA la connessione TCP viene smistata da un thread \emph{listener} verso un thread \emph{working}.
Mentre nei capitoli riguardanti i vari tipi di nodi abbiamo trattato del \emph{listener}, in questo capitolo parleremo 
del \emph{TCPWorkingThread}.

\section{Caratteristiche TCP}
Il servizio offerto da TCP è il trasporto di un flusso di byte bidirezionale tra due applicazioni in esecuzione su host differenti. Il protocollo permette alle due applicazioni di trasmettere contemporaneamente nelle due direzioni, quindi il servizio può essere considerato "Full Duplex" anche se non tutti i protocolli applicativi basati su TCP utilizzano questa possibilità.
Il flusso di byte viene frazionato in blocchi per la trasmissione dall'applicazione a TCP (che normalmente è implementato all'interno del sistema operativo), per la trasmissione all'interno di segmenti TCP, per la consegna all'applicazione che lo riceve, ma questa divisione in blocchi non è per forza la stessa nei diversi passaggi.
TCP è un protocollo orientato alla connessione, ovvero prima di poter trasmettere dati deve stabilire la comunicazione, negoziando una connessione tra mittente e destinatario, che viene esplicitamente chiusa quando non più necessaria. Esso quindi ha le funzionalità per creare, mantenere e chiudere una connessione.
TCP garantisce che i dati trasmessi, se giungono a destinazione, lo facciano in ordine e una volta sola. Questo è realizzato attraverso vari meccanismi di acknowledgment e di ritrasmissione su timeout.
TCP possiede funzionalità di controllo di flusso e di controllo della congestione sulla connessione, attraverso il meccanismo della finestra scorrevole. Questo permette di ottimizzare l'utilizzo della rete anche in caso di congestione.

\section{Il Working Thread nel dettaglio}
\section{Invio di file e divisione del file in parti.}\label{sec:download_tcp}
L'attività principale che Mini-KaZaA prevede è lo scambio di file. I file vengono trasmessi sulla rete, anche su grandi distanze.
I file possono anche essere molto grandi quindi non conviene inviare tutto il file in un unico momento. \`{E} molto più conveniente dividere il file in parti.
Di questo si occupa la parte che invia il file nel \emph{TCPWorkingThread}.
Il codice che esegue queste operazioni è comune a tutti i tipi di nodi, dato che sia SN che ON possono inviare file sulla rete, ed è esposto nel seguente listato.
\begin{lstlisting}
if (incoming_obj instanceof DownloadRequest) {
	//Devo spedire il file richiesto
	DownloadRequest request = 
		(DownloadRequest) incoming_obj;

	MKFileDescriptor file_to_send = 
		this.my_files.getFileList(request.getFile());

	Socket send_sock = new Socket(
			request.getSource().getIaNode(),
			request.getSource().getDoor());

	ObjectOutputStream output = 
		new ObjectOutputStream
		(send_sock.getOutputStream());

	//Avvisa l'inizio del trasferimento.
	DownloadResponse init_response = 
		new DownloadResponse(null, file_to_send.getMd5());

	output.writeObject(init_response);

	File file_pointer = new File(file_to_send.getPath());

	FileInputStream in_file = 
		new FileInputStream(file_pointer);

	byte[] buffer = new byte[4096];

	while (true) {
		try {
			int letti = in_file.read(buffer);
			if (letti > 0) {
				DownloadResponse filepart = 
					new DownloadResponse(buffer, null);
				output.writeObject(filepart);
			} else {
				break;
			}
		} catch (IOException e) {
			break;
		}
	}

	//Chiude la comunicazione
	DownloadResponse stop_sending = 
		new DownloadResponse(null, file_to_send.getMd5());
	output.writeObject(stop_sending);

	in_file.close();
	output.flush();
	output.close();

	send_sock.close();

	
}
\end{lstlisting}
Il procedimento è standard. Ovvero, prima si inizializza la connessione con una prima comunicazione, poi si inviano le varie parti di file e infine si chiude la comunicazione.

Dall'altro lato si troverà chi ha inviato la richiesta di download e che ora si prepara alla ricezione.
Il listato che riceve il file è il duale di quanto appena mostrato ed è il seguente.
\begin{lstlisting}
if (incoming_obj instanceof DownloadResponse){
	DownloadResponse response = 
		(DownloadResponse) incoming_obj;

	//Inizio dell'invio di un file.
	if (response.getPart() == null) {
		Download file_dl = 
			this.my_dl_monitor.getDownload(response.getFile());
		
		File file = new File(
			file_dl.getDownloaderPath() + 
			file_dl.getFile().getFileName());
		
		FileOutputStream file_downloading = 
			new FileOutputStream(file);
		
		while (true) {
			Object read_part = input_object.readObject();

			if (read_part instanceof DownloadResponse) {
				DownloadResponse part = (DownloadResponse) read_part;
				if (part.getFile() == null) {
					//Posso inserire la parte sia 
					//nel monitor che nel file effettivo.
					byte[] buffer = part.getPart();

					if (buffer.length > 0) {
						file_downloading.write(buffer, 0, buffer.length);
						part.setFile(file_dl.getFile().getMd5());
						this.my_dl_monitor.addBytes(part);
					}
				}
				else{
					break;
				}
			}
		}

		file_downloading.flush();
		file_downloading.close();
	}
\end{lstlisting}


